quartz 定时器学习

how2j

1.入门

1.1 几个概念

  • 触发器 Trigger: 什么时候工作 任务 Job: 做什么工作 调度器 Scheduler: 搭配 Trigger和Job

1.2 代码实例

  • 使用quartz定时打印信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//静态导入   不用写成JobBuilder.newJob()
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

public class TestQuartz {
public static void main(String[] args) throws Exception{
//创建调度器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

//定义一个触发器
Trigger trigger = newTrigger().withIdentity("trigger1", "group1") //定义名称和所属的组
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(2) //每隔2秒执行一次
.withRepeatCount(10)) //总共执行11次(第一次执行不基数)
.build();

//定义一个JobDetail
JobDetail job = newJob(MailJob.class) //指定干活的类MailJob
.withIdentity("mailjob1", "mailgroup") //定义任务名称和分组
.usingJobData("email", "admin@10086.com") //定义属性
.build();

//调度加入这个job
scheduler.scheduleJob(job, trigger);

//启动
scheduler.start();

//等待20秒,让前面的任务都执行完了之后,再关闭调度器
Thread.sleep(20000);
scheduler.shutdown(true);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.how2java;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String email = detail.getJobDataMap().getString("email");

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String now = sdf.format(new Date());

System.out.printf("给邮件地址 %s 发出了一封定时邮件, 当前时间是: %s%n" ,email, now);
}
}

2.job管理

2.1 job组成部分

  • Job 其实是由 3 个部分组成:JobDetail: 1、用于描述这个Job是做什么/2. 实现Job的类: 具体干活的 3.JobDataMap: 给 Job 提供参数用的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class TestQuartz {
public static void main(String[] args) throws Exception{
jobDataMap();

}

private static void jobDataMap() throws SchedulerException, InterruptedException {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

Trigger trigger = newTrigger().withIdentity("trigger1", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(2)
.withRepeatCount(10))
.build();

//定义一个JobDetail
JobDetail job = newJob(MailJob.class)
.withIdentity("mailjob1", "mailgroup")
.usingJobData("email", "admin@10086.com")
.build();

//用JobDataMap 修改email
job.getJobDataMap().put("email", "admin@taobao.com");

//调度加入这个job
scheduler.scheduleJob(job, trigger);

//启动
scheduler.start();

//等待20秒,让前面的任务都执行完了之后,再关闭调度器
Thread.sleep(20000);
scheduler.shutdown(true);
}
}

2.2 job并发

  • 解决 几个线程同时备份数据库,引发无法预计的混乱
  • @DisallowConcurrentExecution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@DisallowConcurrentExecution
public class DatabaseBackupJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
String database = detail.getJobDataMap().getString("database");

System.out.printf("给数据库 %s 备份, 耗时10秒 %n" ,database);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}